import 'dart:typed_data';
import 'package:amap_plugin/index.dart';
import 'package:flutter/services.dart' show rootBundle;

class MarkerOptions {
  ///获取Marker覆盖物的标题。
  final String title;

  ///获取Marker覆盖物的坐标位置。
  final LatLng position;

  ///设置Marker覆盖物是否可拖拽。
  final bool draggable;

  ///设置Marker覆盖物是否平贴地图。
  final bool flat;

  ///设置Marker覆盖物的坐标是否是Gps，默认为false。
  final bool isGps;

  ///设置 Marker覆盖物的 文字描述
  final String snippet;

  ///设置Marker覆盖物的图标
  final BitmapDescriptor icon;

  ///设置Marker覆盖物的动画帧图标列表，多张图片模拟gif的效果
  final List<BitmapDescriptor> icons;

  ///设置Marker覆盖物的透明度
  final double alpha;

  ///设置Marker覆盖物的InfoWindow是否允许显示,默认为true
  final bool infoWindowEnable;

  ///获取Marker覆盖物是否可见。
  final bool isVisible;

  ///设置多少帧刷新一次图片资源，Marker动画的间隔时间，值越小动画越快。
  final int period;

  ///设置Marker覆盖物的图片旋转角度，从正北开始，逆时针计算。
  final double rotateAngle;

  ///设置Marker覆盖物的InfoWindow相对Marker的偏移。
  final InfoWindowOffset infoWindowOffset;

  ///设置Marker覆盖物 zIndex。
  final double zIndex;

  ///动画，非null表示marker使用动画
  final MarkerAnimation markerAnimation;

  ///设置Marker覆盖物的锚点比例。锚点是marker 图标接触地图平面的点。图标的左顶点为（0,0）点，右底点为（1,1）点。
  ///默认为（0.5,1.0）
  final AnchorRatio anchorRatio;

  ///封装数据为Map对象，传递给Native
  Future<Map<String, dynamic>> getMap() async {
    var rev = Map<String, dynamic>();
    rev["lat"] = this.position.latitude;
    rev["lng"] = this.position.longitude;
    rev["icon_width"] = this.icon?.width;
    rev["icon_height"] = this.icon?.height;
    rev["icon_data"] = await this.icon?.data;
    
    if (this.icons != null) {
      for (var i = 0; i < this.icons.length; i++) {
        var prefix = "${i}_icons";
        rev["${prefix}_width"] = this.icons[i]?.width;
        rev["${prefix}_height"] = this.icons[i]?.height;
        rev["${prefix}_data"] = this.icons[i]?.data;
      }
    }
    
    rev["title"] = this.title;
    rev["draggable"] = this.draggable;
    rev["flat"] = this.flat;
    rev["isGps"] = this.isGps;
    rev["snippet"] = this.snippet;
    rev["alpha"] = this.alpha;
    rev["infoWindowEnable"] = this.infoWindowEnable;
    rev["isVisible"] = this.isVisible;
    rev["period"] = this.period;
    rev["rotateAngle"] = this.rotateAngle;
    rev["zIndex"] = this.zIndex;
    if (this.infoWindowOffset != null) {
      rev["infoWindowOffset_offsetX"] = this.infoWindowOffset.offsetX;
      rev["infoWindowOffset_offsetY"] = this.infoWindowOffset.offsetY;
    }
    if (this.anchorRatio != null) {
      rev["anchorRatio_horizontal"] = this.anchorRatio.horizontal;
      rev["anchorRatio_vertical"] = this.anchorRatio.vertical;
    }
    rev['markerAnimation'] = this.markerAnimation?.getMap();
    return rev;
  }

  MarkerOptions(
      {this.position,
      this.title,
      this.flat,
      this.isGps,
      this.snippet,
      this.icons,
      this.infoWindowEnable,
      this.isVisible,
      this.period,
      this.rotateAngle,
      this.infoWindowOffset,
      this.zIndex,
      this.alpha,
      this.icon,
      this.anchorRatio,
      this.draggable,
      this.markerAnimation});
}

///设置Marker覆盖物的图标
class BitmapDescriptor {

  ///返回 Bitmap的宽度。
  final double width;
  ///返回 Bitmap 的高度
  final double height;

  ///标记图像路径[assets/*]配置，需要在文件[pubspec.yaml]中配置
  ///```
  ///assets:
  ///  -images/p.jpeg
  /// ```
  final String imagePath;

  ///获取对应的Bitmap 对象
  Future<Uint8List> get data async {
    var data = await rootBundle.load(this.imagePath);
    return data.buffer.asUint8List();
  }

  ///marker标记的位图信息
  ///
  ///[imagePath] 位图路径 [width]和[height]可选，[isAnimation]标记是否启用动画效果
  BitmapDescriptor(
    this.imagePath, {
    this.width,
    this.height,
  });
}

class AnchorRatio {
  ///锚点水平范围的比例，建议传入0 到1 之间的数值
  final double horizontal;
  ///锚点垂直范围的比例，建议传入0 到1 之间的数值
  final double vertical;
  AnchorRatio(this.horizontal, this.vertical);
}

///marker提示窗口偏移量
class InfoWindowOffset {
  final int offsetX;
  final int offsetY;
  InfoWindowOffset(this.offsetX, this.offsetY);
}

///旋转动画
const String ANIMATION_TYPE_ROTATE = "rotate";
///透明度动画
const String ANIMATION_TYPE_ALPHA = "alpha";
///缩放动画
const String ANIMATION_TYPE_SCALE = "scale";
///移动动画
const String ANIMATION_TYPE_TRANSLATE = "translate";


const String INTERPOLATOR_TYPE_BOUNCE = "BounceInterpolator";

///需要传递参数 double input
const String INTERPOLATOR_TYPE_DECELERATE = "DecelerateInterpolator";

///传递参数 double input
const String INTERPOLATOR_TYPE_LINEAR = "LinearInterpolator";

/// 传递参数 double input
const String INTERPOLATOR_TYPE_LINEAR_OUT_SLOW_IN =
    "LinearOutSlowInInterpolator";
///// 传递参数 double tension
///Amount of anticipation. When tension equals 0.0f, there is
///no anticipation and the interpolator becomes a simple
///acceleration interpolator.
const String INTERPOLATOR_TYPE_ANTICIPATE = "AnticipateInterpolator";

/// 传递参数 tension;
const String INTERPOLATOR_TYPE_ANTICIPATE_OVER_SHOOT =
    "AnticipateOvershootInterpolator"; //
///参数 cycles
const String INTERPOLATOR_TYPE_CYCLE = "CycleInterpolator";
const String INTERPOLATOR_TYPE_FAST_OUT_LINEAR_IN =
    "FastOutLinearInInterpolator";
const String ININTERPOLATOR_TYPE_FAST_OUT_SLOW = "FastOutSlowInInterpolator";
const String INTERPOLATOR_TYPE_OVER_SHOOT =
    "OvershootInterpolator"; // float tension

/// 模拟重力加速度
const String INTERPOLATOR_TYPE_ACCELERATION = "AccelerationInInterpolator";

///动画执行后保持在第一帧
const int ANIMATION_FILL_MODE_BACKWARDS = 0;

///动画执行后保持在最后一帧
const int ANIMATION_FILL_MODE_FORWARDS = 1;

/// 无限期地重复动画.
const int ANIMATION_REPEAT_MODEL_INFINITE = 0;

///动画结束后从头播放，最大重复次数受Animation.setRepeatCount(int) 限制
const int ANIMATION_REPEAT_MODEL_RESTART = 1;

///动画结束后从尾倒放，最大重复次数受Animation.setRepeatCount(int) 限制
const int ANIMATION_REPEAT_MODEL_REVERSE = 2;

///抽象动画
///
///[duration]动画延时，[animationType]动画类型,字符串类型，值为[ANIMATION_TYPE_*]
///[repeatCount]动画重复次数，[interpolatorType]读取常量 [INTERPOLATOR_TYPE_*]的值，动画曲线效果，
///[fillMode]动画执行完后状态值，见常量[ANIMATION_FILL_MODE_*]的值
abstract class MarkerAnimation {
  ///设置动画持续时间,如果设置为负数,会修正为0
  final int duration;
  final String animationType;

  ///获取动画重复执行的次数,默认为0
  final int repeatCount;

  ///插值器类型常量 [INTERPOLATOR_TYPE_*]的值
  final String interpolatorType;

  ///不同[interpolatorType]对应的不同的值
  ///[INTERPOLATOR_TYPE_BOUNCE]
  final double interpolatorValue;

  ///获取动画执行完成后的状态,读取常量[ANIMATION_FILL_MODE_*]的值
  final int fillMode;

  ///重复执行的模式. 读取常量 [ANIMATION_REPEAT_MODEL_*]的值
  final int repeatMode;

  Map<String, Object> getMap();
  MarkerAnimation(
    this.duration,
    this.animationType,
    this.repeatCount,
    this.interpolatorType, {
    this.interpolatorValue,
    this.fillMode,
    this.repeatMode,
  });
}

///控制旋转的动画类
class RotateAnimation extends MarkerAnimation {
  final double fromdegree;
  final double todegree;

  ///[duration]动画延时，[animationType]动画类型,字符串类型，值为[ANIMATION_TYPE_*]
  ///[repeatCount]动画重复次数，[interpolatorType]读取常量 [INTERPOLATOR_TYPE_*]的值，动画曲线效果，
  ///[fillMode]动画执行完后状态值，见常量[ANIMATION_FILL_MODE_*]的值
  ///[fromdegree]起始角度[todegree]目标角度
  RotateAnimation(
    int duration,
    this.fromdegree,
    this.todegree, {
    int repeatCount = 0,
    String interpolatorType,
    double interpolatorValue,
    int fillMode,
    int repeatMode,
  }) : super(duration, ANIMATION_TYPE_ROTATE, repeatCount, interpolatorType,
            interpolatorValue: interpolatorValue,
            fillMode: fillMode,
            repeatMode: repeatMode);
  @override
  Map<String, Object> getMap() {
    var rev = Map<String, Object>();
    rev["duration"] = this.duration;
    rev["animationType"] = this.animationType;
    rev["repeatCount"] = this.repeatCount ?? 0;
    rev["interpolatorValue"] = this.interpolatorValue;
    rev["fillMode"] = this.fillMode;
    rev["repeatMode"] = this.repeatMode;
    rev["fromdegree"] = this.fromdegree;
    rev["todegree"] = this.todegree;
    return rev;
  }
}

///控制透明度的动画类
class AlphaAnimation extends MarkerAnimation {
  final double fromAlpha;
  final double toAlpha;

  ///[duration]动画延时，[animationType]动画类型,字符串类型，值为[ANIMATION_TYPE_*]
  ///[repeatCount]动画重复次数，[interpolatorType]读取常量 [INTERPOLATOR_TYPE_*]的值，动画曲线效果，
  ///[fillMode]动画执行完后状态值，见常量[ANIMATION_FILL_MODE_*]的值
  ///[fromAlpha]起始透明度，[toAlpha]目标透明度
  ///控制透明度的动画类
  ///透明度范围[0,1], 1为不透明
  AlphaAnimation(
    int duration,
    this.fromAlpha,
    this.toAlpha, {
    int repeatCount = 0,
    String interpolatorType,
    double interpolatorValue,
    int fillMode,
    int repeatMode,
  }) : super(duration, ANIMATION_TYPE_ALPHA, repeatCount, interpolatorType,
            interpolatorValue: interpolatorValue,
            fillMode: fillMode,
            repeatMode: repeatMode);

  @override
  Map<String, Object> getMap() {
    var rev = Map<String, Object>();
    rev["duration"] = this.duration;
    rev["animationType"] = this.animationType;
    rev["repeatCount"] = this.repeatCount ?? 0;
    rev["interpolatorValue"] = this.interpolatorValue;
    rev["fromAlpha"] = this.fromAlpha;
    rev["fillMode"] = this.fillMode;
    rev["repeatMode"] = this.repeatMode;
    rev["toAlpha"] = this.toAlpha;
    return rev;
  }
}

///控制缩放的动画类,比如要实现一个Marker生长动画,可以使用 (0,1,0,1)
class ScaleAnimation extends MarkerAnimation {
  ///动画开始时横坐标位置
  final double fromX;

  ///动画结束时横坐标位置
  final double toX;

  ///动画开始时纵坐标位置
  final double fromY;

  ///动画结束时纵坐标位置
  final double toY;

  ///[duration]动画延时，[animationType]动画类型,字符串类型，值为[ANIMATION_TYPE_*]
  ///[repeatCount]动画重复次数，[interpolatorType]读取常量 [INTERPOLATOR_TYPE_*]的值，动画曲线效果，
  ///[fillMode]动画执行完后状态值，见常量[ANIMATION_FILL_MODE_*]的值
  ///[fromX]动画开始时横坐标位置,[toX]动画结束时横坐标位置,[fromY] 动画开始时纵坐标位置[toY]动画结束时纵坐标位置
  ScaleAnimation(
    int duration,
    this.fromX,
    this.toX,
    this.fromY,
    this.toY, {
    int repeatCount = 0,
    String interpolatorType,
    double interpolatorValue,
    int fillMode,
    int repeatMode,
  }) : super(duration, ANIMATION_TYPE_ALPHA, repeatCount, interpolatorType,
            interpolatorValue: interpolatorValue,
            fillMode: fillMode,
            repeatMode: repeatMode);

  @override
  Map<String, Object> getMap() {
    var rev = Map<String, Object>();
    rev["duration"] = this.duration;
    rev["animationType"] = this.animationType;
    rev["repeatCount"] = this.repeatCount ?? 0;
    rev["interpolatorValue"] = this.interpolatorValue;
    rev["fromX"] = this.fromX;
    rev["toX"] = this.toX;
    rev["fromY"] = this.fromY;
    rev["toY"] = this.toY;
    rev["fillMode"] = this.fillMode;
    rev["repeatMode"] = this.repeatMode;
    return rev;
  }
}

class TranslateAnimation extends MarkerAnimation{

  final double targetLat;
  final double targetLng;
  TranslateAnimation(this.targetLat,this.targetLng,
   duration, String animationType, int repeatCount, String interpolatorType) 
  : super(duration, animationType, repeatCount, interpolatorType);
  
  @override
  Map<String, Object> getMap() {
   var rev = Map<String, Object>();
    rev["duration"] = this.duration;
    rev["animationType"] = this.animationType;
    rev["repeatCount"] = this.repeatCount ?? 0;
    rev["interpolatorValue"] = this.interpolatorValue;
    rev["targetLat"] = this.targetLat;
    rev["targetLng"] = this.targetLng;
    rev["fillMode"] = this.fillMode;
    rev["repeatMode"] = this.repeatMode;
    return rev;
  }

}